home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / DB_CLIPP / 0769A.ZIP / RDDBASE.C < prev    next >
C/C++ Source or Header  |  1987-06-19  |  7KB  |  216 lines

  1. /* ---------- "C source to read dBASE files" ---------- */
  2. /* Here is the C code that allows you to read a DBASE-III file. I verified
  3. that it works under Microsoft C v4.0. Hope it does every thing you need.
  4. I am not sure where it came from, so hopefully I am not violating anyones
  5. copyrights :-). Have fun.
  6.  
  7. Greg Twaites
  8. SICOM Inc.
  9. !ihnp4!sun!sunburn!sicom!twaites
  10. */
  11. /*
  12.  * These functions are used to read dbase files.
  13.  *
  14.  * These functions are provided by Valour Software as a gift.
  15.  *
  16.  * The program is for test purposes only.  No warranty is expressed nor
  17.  * implied. USE AT YOUR OWN RISK!
  18.  *
  19.  *
  20.  */
  21.  
  22. #define LINT_ARGS
  23.  
  24. #include <fcntl.h>
  25. #include <sys\types.h>
  26. #include <sys\stat.h>
  27. #include <io.h>
  28. #include <malloc.h>
  29.  
  30. typedef  struct dbase_head {
  31.     unsigned char   version;     /*03 for dbIII and 83 for dbIII w/memo file*/
  32.     unsigned char   l_update[3];                    /*yymmdd for last update*/
  33.     unsigned long   count;                       /*number of records in file*/
  34.     unsigned int    header;                           /*length of the header
  35.                                                        *includes the \r at end
  36.                                                        */
  37.     unsigned int    lrecl;                            /*length of a record
  38.                                                        *includes the delete
  39.                                                        *byte
  40.                                                        */
  41.     unsigned char   reserv[20];
  42.     } DBASE_HEAD;
  43.  
  44. typedef struct dbase_fld {
  45.     char    name[11];                                           /*field name*/
  46.     char    type;                                               /*field type*/
  47. #define DB_FLD_CHAR  'C'
  48. #define DB_FLD_NUM   'N'
  49. #define DB_FLD_LOGIC 'L'
  50. #define DB_FLD_MEMO  'M'
  51. #define DB_FLD_DATE  'D'
  52.     /* A-T uses large data model but drop it for now */
  53.     char far        *data_ptr;                         /*pointer into buffer*/
  54.     unsigned char   length;                                   /*field length*/
  55.     unsigned char   dec_point;                         /*field decimal point*/
  56.     unsigned char   fill[14];
  57.     } DBASE_FIELD;
  58.  
  59. typedef struct fld_list {
  60.     struct fld_list *next;
  61.     DBASE_FIELD     *fld;
  62.     char            *data;
  63.     } FLD_LIST;
  64.  
  65. DBASE_HEAD  dbhead={0};
  66. FLD_LIST    *db_fld_root=0;
  67. char        *Buffer;
  68. char        buf_work[255];
  69. int         dbfile;
  70.  
  71. /*------------------------------------------------------------code-------*/
  72. main(argc,argv)
  73. int     argc;
  74. char    *argv[];
  75. {
  76.     if(argc!=2)
  77.         error("Usage is db_dump filename.dbf");
  78.     dbfile=open(argv[1],O_RDONLY);
  79.     if(dbfile==-1)
  80.         error("Unable to open file");
  81.     db3_read_dic();
  82.     db3_print_recs(5);
  83.     printf("\n\n\t\t\tProcessing complete");
  84.     close(dbfile);
  85.     exit(0);
  86. }
  87.  
  88.  
  89. /******************************************************
  90.                                          db3_read_dic()
  91. This function is called with a file name to
  92. read to create a record type to support the
  93. dbase file
  94. ******************************************************/
  95.  
  96. db3_read_dic()
  97. {
  98.     int             fields;
  99.     DBASE_FIELD     *fld;
  100.  
  101.     if(dbfile==-1) {
  102.         printf("open failed");
  103.         exit(200);
  104.         }
  105.     read(dbfile,&dbhead,sizeof(DBASE_HEAD));
  106.     if( !(dbhead.version==3 || dbhead.version==0x83) )
  107.         error("\n\aVersion %d not supported",dbhead.version);
  108.  
  109.     printf("update year    %3d\n",dbhead.l_update[0]);
  110.     printf("update mon     %3d\n",dbhead.l_update[1]);
  111.     printf("update day     %3d\n",dbhead.l_update[2]);
  112.     printf("number of recs %3d\n",dbhead.count);
  113.     printf("header length  %3d\n",dbhead.header);
  114.     printf("record length  %3d\n",dbhead.lrecl);
  115.     Buffer=malloc(dbhead.lrecl);
  116.  
  117.     fields=(dbhead.header-1)/32-1;
  118.     printf("\nField Name\tType\tLength\tDecimal Pos\n");
  119.     while(fields--) {
  120.         fld=(DBASE_FIELD *)malloc(sizeof(DBASE_FIELD));
  121.         if(!fld)
  122.             error("\n\aNot enough memory\n");
  123.         read(dbfile,fld,sizeof(DBASE_FIELD));
  124.         printf("%-10s\t  %c\t  %3d\t  %3d\n",fld->name,fld->type,
  125.                                      fld->length,fld->dec_point);
  126.         stack_field(fld);
  127.         }
  128.     read(dbfile,Buffer,1);              /*read the silly little \r character*/
  129.     return;
  130. }
  131.  
  132. /******************************************************
  133.                                         db3_print_recs()
  134. Read records and print the data
  135. ******************************************************/
  136.  
  137. db3_print_recs(cnt)
  138. int     cnt;
  139. {
  140.     int     bytes;
  141.  
  142.     while(cnt) {
  143.         bytes=read(dbfile,Buffer,dbhead.lrecl);
  144.         if(bytes!=dbhead.lrecl)
  145.             break;
  146.         if(Buffer[0]!='*') {
  147.             db3_print();
  148.             cnt--;
  149.             }
  150.         }
  151.     return;
  152. }
  153.  
  154.  
  155. /******************************************************
  156.                                           db3_print()
  157. Print a single record
  158. ******************************************************/
  159.  
  160. db3_print()
  161. {
  162.     FLD_LIST    *list, *temp;
  163.  
  164.     temp=db_fld_root;
  165.     printf("\n");
  166.     while(temp) {
  167.         memcpy(buf_work,temp->data,temp->fld->length);
  168.         buf_work[temp->fld->length]='\0';
  169.         printf("%-10s=%s\n",temp->fld->name,buf_work);
  170.         temp=temp->next;
  171.         }
  172.     return;
  173. }
  174.  
  175. /******************************************************
  176.                                          stack_field()
  177. Add a field to the linked list of fields
  178. ******************************************************/
  179.  
  180. stack_field(fld)
  181. DBASE_FIELD *fld;
  182. {
  183.     FLD_LIST    *list, *temp;
  184.  
  185.     list=(FLD_LIST *)calloc(1,sizeof(FLD_LIST));
  186.     if(!list)
  187.         error("\n\aNot enough memory\n");
  188.     list->fld=fld;
  189.     if(!db_fld_root) {
  190.         list->data=Buffer+1;                            /*skip delete byte*/
  191.         db_fld_root=list;
  192.         return;
  193.         }
  194.     temp=db_fld_root;
  195.     while(temp->next)
  196.         temp=temp->next;
  197.     temp->next=list;
  198.     list->data=temp->data + temp->fld->length;
  199.     return;
  200. }
  201.  
  202.  
  203. /******************************************************
  204.                                             error()
  205. Produce error msg and abort
  206. ******************************************************/
  207.  
  208. error(msg)
  209. char    *msg;
  210. {
  211.     printf(msg);
  212.     close(dbfile);
  213.     exit(255);
  214. }
  215. /* End of text from inmet:comp.sys.ibm.pc */
  216.